package com.boot2.core.utils;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * @author zhangweilin
 * @date 2020/8/4 11:31
 * @Description: 时间范围工具，范围为，以当前时间往前推
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TimeSegment {

    private LocalDateTime localDateTime;
    private LocalDateTime startTime;
    private LocalDateTime endTime;
    private TimeSegmentType timeSegmentType;

    public TimeSegment(TimeSegmentType timeSectionType) {
        this(LocalDateTime.now(), timeSectionType);
    }

    public TimeSegment(Date startTime, Date endTime) {
        this.startTime = LocalDateTimeUtil.date2LocalDateTime(startTime);
        this.endTime = LocalDateTimeUtil.date2LocalDateTime(endTime);
    }

    public TimeSegment(LocalDateTime startTime, LocalDateTime endTime) {
        this.startTime = startTime;
        this.endTime = endTime;
    }

    public TimeSegment(LocalDateTime localDateTime, TimeSegmentType timeSegmentType) {
        if (localDateTime == null) {
            throw new IllegalArgumentException("localDateTime is null.");
        }

        localDateTime = localDateTime.withNano(0).withSecond(0);
        this.localDateTime = localDateTime;
        this.timeSegmentType = timeSegmentType;
        warpTimeSegment(localDateTime, timeSegmentType);
    }

    public TimeSegment(Date time, TimeSegmentType timeSegmentType) {
        LocalDateTime localDateTime = LocalDateTimeUtil.date2LocalDateTime(time);
        if (localDateTime == null) {
            throw new IllegalArgumentException("localDateTime is null.");
        }
        localDateTime = localDateTime.withNano(0).withSecond(0);
        this.localDateTime = localDateTime;
        this.timeSegmentType = timeSegmentType;
        warpTimeSegment(localDateTime, timeSegmentType);
    }

    /**
     * 重算起始时间
     *
     * @param timeSegmentType
     */
    public TimeSegment setTimeSegmentType(TimeSegmentType timeSegmentType) {
        this.timeSegmentType = timeSegmentType;
        warpTimeSegment(localDateTime, timeSegmentType);
        return this;
    }

    /**
     * 传一个基准时间，重新算起始时间范围
     *
     * @param localDateTime
     * @return
     */
    public TimeSegment reCalcLocalDateTime(LocalDateTime localDateTime) {
        setLocalDateTime(localDateTime);
        setTimeSegmentType(this.timeSegmentType);
        return this;
    }

    public TimeSegment setStartTime(LocalDateTime startTime) {
        this.startTime = startTime;
        return this;
    }

    public TimeSegment setEndTime(LocalDateTime endTime) {
        this.endTime = endTime;
        return this;
    }

    public TimeSegment setLocalDateTime(LocalDateTime localDateTime) {
        this.localDateTime = localDateTime;
        return this;
    }

    public TimeSegment setStartTime(Date startTime) {
        this.startTime = LocalDateTimeUtil.date2LocalDateTime(startTime);
        return this;
    }

    public TimeSegment setEndTime(Date endTime) {
        this.endTime = LocalDateTimeUtil.date2LocalDateTime(endTime);
        return this;
    }

    public TimeSegment setLocalDateTime(Date localDateTime) {
        this.localDateTime = LocalDateTimeUtil.date2LocalDateTime(localDateTime);
        return this;
    }

    /**
     * 时间起始 范围整体自增滚动
     *
     * @param count
     * @return
     */
    public TimeSegment add(int count) {
        switch (timeSegmentType) {
            //
            case HOUR:
                localDateTime = localDateTime.plusHours(count);
                break;
            //
            case DAY:
                localDateTime = localDateTime.plusDays(count);
                break;
            //
            case WEEK:
                localDateTime = localDateTime.plusWeeks(count);
                break;
            //
            case MONTH:
                localDateTime = localDateTime.plusMonths(count);
                break;
            //
            case YEAR:
                localDateTime = localDateTime.plusYears(count);
                break;
            //
            default:
                throw new IllegalArgumentException("invalid timeSegmentType.");
        }
        reCalcLocalDateTime(localDateTime);
        return this;
    }

    private void warpTimeSegment(LocalDateTime localDateTime, TimeSegmentType timeSegmentType) {
        switch (timeSegmentType) {
            case MIN:
                this.endTime = localDateTime.withSecond(0).withNano(0);
                this.startTime = this.endTime.minusMinutes(1);
                break;
            //
            case HOUR:
                this.endTime = localDateTime.withMinute(0).withSecond(0).withNano(0);
                this.startTime = this.endTime.minusHours(1);
                break;
            //
            case DAY:
                this.endTime = localDateTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
                this.startTime = this.endTime.minusDays(1);
                break;
            //
            case WEEK:
                this.endTime = localDateTime.with(DayOfWeek.MONDAY).withHour(0).withMinute(0).withSecond(0).withNano(0);
                this.startTime = this.endTime.minusWeeks(1);
                break;
            //
            case MONTH:
                this.endTime = localDateTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
                this.startTime = this.endTime.minusMonths(1);
                break;
            //
            case YEAR:
                this.endTime = localDateTime.withMonth(1).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
                this.startTime = this.endTime.minusYears(1);
                break;
            //
            default:
                throw new IllegalArgumentException("invalid timeSegmentType.");
        }
    }

    /**
     * 获取Date类型，mybatis sql server不支持直接的LocalDateTime
     *
     * @return
     */
    public Date getStartTimeDate() {
        return LocalDateTimeUtil.localDateTime2Date(startTime);
    }

    /**
     * 获取Date类型，mybatis sql server不支持直接的LocalDateTime
     *
     * @return
     */
    public Date getEndTimeDate() {
        return LocalDateTimeUtil.localDateTime2Date(endTime);
    }

}
